package com.jt.www.common.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jt.www.common.service.zqsign.dependency.*;
import com.jt.www.dao.mapper.zq.ZqContractMapper;
import com.jt.www.model.reps.GenericResponse;
import com.jt.www.model.zq.ZqContract;
import com.jt.www.util.DateUtils;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @描述： 众签接口
 * @作者： lux
 * @创建日期： 2018-9-6 14:08
 * @版权： 江泰保险经纪股份有限公司
 */
@Service
public class ZqService {


    private final Logger log = LoggerFactory.getLogger(this.getClass());

    @Value("${jtpf.zq.zqid}")
    public String ZQID = "";

    @Value("${jtpf.zq.privateKey}")
    public String PRIVATE_KEY = "";

    @Value("${jtpf.zq.requestUrl}")
    public String REQUEST_URL = "";

    @Autowired
    public ZqContractMapper zqContractMapper;

    /**
     * 创建企业数字证书
     *
     * @param certificate 社会统一代码证
     * @param address     企业注册地址
     * @param contact     联系人
     * @param mobile      联系手机号
     * @param branchcode  分公司编码
     * @param brancheName 分公司名称
     * @return
     */
    public String regEnterprise(String certificate, String address, String contact, String mobile, String branchcode, String brancheName) {
        String privateKey = PRIVATE_KEY;
        String requestUrl = REQUEST_URL + "entpReg";
        String zqid = ZQID;

        EncryptData ed = new EncryptData();

        Map<String, String> map = new HashMap<>();

        map.put("zqid", zqid);//商户的zqid,该值需要与private_key对应
        map.put("user_code", "JT0114003");//用户唯一标示，该值不能重复 JT0114003
        map.put("name", "江泰保险经纪股份有限公司太原小店营业部");//企业名称
        map.put("certificate", "91140100MA0K57WL7N");//营业执照号或社会统一代码
        map.put("address", "山西省太原市小店区学府街132号华宇百花谷写字楼D座20+0号"); //企业注册地址
        map.put("contact", "李燚");//联系人
        map.put("mobile", "18634396521");//联系电话（手机号码）

        String signVal = ed.encrptData(map, privateKey);

        map.put("sign_val", signVal); //请求参数的签名值
        String responseStr = "";//向服务端发送请求，并接收请求结果
        try {
            responseStr = HttpRequest.sendPost(requestUrl, map);
            JSONObject object = JSONObject.parseObject(responseStr);

        } catch (IOException e) {
            e.printStackTrace();
            responseStr = GenericResponse.ng("链接异常").toString();
        }
        log.info(responseStr);
        return responseStr;
    }

    /**
     * 创建企业数字证书
     *
     * @param certificate 社会统一代码证
     * @param address     企业注册地址
     * @param contact     联系人
     * @param mobile      联系手机号
     * @param branchcode  分公司编码
     * @param brancheName 分公司名称
     * @return
     */
    public String updateEnterprise(String certificate, String address, String contact, String mobile, String branchcode, String brancheName) {
        String privateKey = PRIVATE_KEY;
        String requestUrl = REQUEST_URL + "entpUpdate";
        String zqid = ZQID;

        EncryptData ed = new EncryptData();

        Map<String, String> map = new HashMap<>();

        map.put("zqid", zqid);//商户的zqid,该值需要与private_key对应
        map.put("user_code", branchcode);//用户唯一标示，该值不能重复
        map.put("name", brancheName);//企业名称
        map.put("certificate", certificate);//营业执照号或社会统一代码
        map.put("address", address); //企业注册地址
        map.put("contact", contact);//联系人
        map.put("mobile", mobile);//联系电话（手机号码）

        String signVal = ed.encrptData(map, privateKey);

        map.put("sign_val", signVal); //请求参数的签名值
        String responseStr = null;//向服务端发送请求，并接收请求结果
        try {
            responseStr = HttpRequest.sendPost(requestUrl, map);
            JSONObject object = JSONObject.parseObject(responseStr);
        } catch (IOException e) {
            e.printStackTrace();
            responseStr = GenericResponse.ng("链接异常").toString();
        }
        log.info(responseStr);
        return responseStr;
    }

    /**
     * 创建个人数字证书
     *
     * @param name     人名称
     * @param idCardNo 身份证号
     * @param mobile   联系手机号
     * @return
     */
    public String personReg(String name, String idCardNo, String mobile) {
        String privateKey = PRIVATE_KEY;
        String requesUrl = REQUEST_URL + "personRegNV";

        EncryptData ed = new EncryptData();

        Map<String, String> map = new HashMap<>();

        map.put("zqid", ZQID);//商户的zqid,该值需要与private_key对应
        map.put("user_code", idCardNo);//用户唯一标示，该值不能重复
        map.put("name", name);//平台方用户姓名
        map.put("id_card_no", idCardNo);//身份证号
        map.put("mobile", mobile);//联系电话（手机号码）

        String signVal = ed.encrptData(map, privateKey);

        map.put("sign_val", signVal); //请求参数的签名值
        String responseStr = null;//向服务端发送请求，并接收请求结果
        try {
            responseStr = HttpRequest.sendPost(requesUrl, map);
        } catch (IOException e) {
            e.printStackTrace();
            responseStr = GenericResponse.ng("链接异常").toString();
        }
        log.info(responseStr);
        return responseStr;
    }

    /**
     * 修改个人数字证书
     *
     * @param name     人名称
     * @param idCardNo 身份证号
     * @param mobile   联系手机号
     * @return
     */
    public String updatePersonReg(String name, String idCardNo, String mobile) {
        String privateKey = PRIVATE_KEY;
        String requestUrl = REQUEST_URL + "personUpdateNV";

        EncryptData ed = new EncryptData();

        Map<String, String> map = new HashMap<>();

        map.put("zqid", ZQID);//商户的zqid,该值需要与private_key对应
        map.put("user_code", idCardNo);//用户唯一标示，该值不能重复
        map.put("name", name);//平台方用户姓名
        map.put("id_card_no", idCardNo);//身份证号
        map.put("mobile", mobile);//联系电话（手机号码）

        String signVal = ed.encrptData(map, privateKey);

        map.put("sign_val", signVal); //请求参数的签名值
        String responseStr = null;//向服务端发送请求，并接收请求结果
        try {
            responseStr = HttpRequest.sendPost(requestUrl, map);
        } catch (IOException e) {
            e.printStackTrace();
            responseStr = GenericResponse.ng("链接异常").toString();
        }
        log.info(responseStr);
        return responseStr;
    }

    /**
     * 上传公章
     *
     * @param userCode
     * @param file
     * @return
     * @throws FileNotFoundException
     */
    public String signatureChange(String userCode, MultipartFile file) {
        String privateKey = PRIVATE_KEY;
        String requestUrl = REQUEST_URL + "signatureChange";
        String zqid = ZQID;
        EncryptData ed = new EncryptData();

        Map<String, String> map = new HashMap<>();
        map.put("zqid", zqid);// ---------需要用户修改
        map.put("user_code", "JT0114003");// ---------需要用户修改
        byte[] byteArray = new byte[0];
        String responseStr = "";
        try {
            byteArray = IOUtils.toByteArray(file.getInputStream());
            String encode = Base64.encode(byteArray);
            map.put("signature", encode);// ---------需要用户修改
            String signVal = ed.encrptData(map, privateKey);
            map.put("sign_val", signVal); // 请求参数的签名
            System.out.println("请求参数：" + map.toString());
            responseStr = HttpRequest.sendPost(requestUrl, map);// 向服务端发送请求，并接收请求结果
            System.out.println("请求结果：" + responseStr);// 输出服务器响应结果
        } catch (IOException e) {
            e.printStackTrace();
            responseStr = GenericResponse.ng("链接异常").toString();
        }
        log.info(responseStr);
        return responseStr;
    }


    /**
     * 创建合同
     *
     * @param vo 参数
     * @return
     */
    public String createContract(ZQVO vo) {
        String privateKey = PRIVATE_KEY;
        String requestUrl = REQUEST_URL + "pdfTemplate";
        String zqid = ZQID;
        EncryptData ed = new EncryptData();

        Map<String, String> map = new HashMap<>();

        //众签提供给开发者的应用标识码,该值需要与private_key对应
        map.put("zqid", zqid);
        //自行创建合同编号，该值不可重复使用
        map.put("no", vo.getNo());
        //商户平台合同名称
        map.put("name", vo.getName());
        //商户平台存储在众签平台的合同模板编号
        map.put("t_no", vo.getTno());
        //表单的json串
        map.put("contract_val", "{'jsonVal':[{'no':'604太原小店营业部1201910153784','consignor':'" + vo.getConsignor() + "','consignee':'" + vo.getConsignee() + "','signDate':'" + vo.getSignDate() + "','idType':'" + vo.getIdType() +
                "','idNo':'" + vo.getIdNo() + "','consignorPhone':'" + vo.getConsignorPhone() + "','Signer1':'" + vo.getIdNo() + "','Signer2':'" + vo.getSigner2() + "','regUrl':'" + vo.getRegUrl() + "'}]}");
        String signVal = ed.encrptData(map, privateKey);//对请求进行签名加密
        map.put("sign_val", signVal); //请求参数的签名值
        log.info("表单JSON：{}", map.get("contract_val"));
        String responseStr = null;//向服务端发送请求，并接收请求结果
        try {
            responseStr = HttpRequest.sendPost(requestUrl, map);
        } catch (IOException e) {
            e.printStackTrace();
            responseStr = GenericResponse.ng("链接异常").getBody().toString();
        }
        log.info(responseStr);
        return responseStr;
    }

    /**
     * 自动签名
     *
     * @param no      合同号
     * @param signers 公章签名
     * @return
     */
    public String signAuto(String no, String signers) {
        String private_key = PRIVATE_KEY;
        String request_url = REQUEST_URL + "signAuto";
        String zqid = ZQID;
        EncryptData ed = new EncryptData();

        Map<String, String> map = new HashMap<String, String>();

        map.put("zqid", zqid);//商户的zqid,该值需要与private_key对应
        map.put("no", no);//已存在的合同编号
        map.put("signers", signers);//签署人user_code

        String sign_val = ed.encrptData(map, private_key);
        map.put("sign_val", sign_val); //请求参数的签名值
        String response_str = null;//向服务端发送请求，并接收请求结果
        try {
            response_str = HttpRequest.sendPost(request_url, map);
        } catch (IOException e) {
            e.printStackTrace();
            response_str = GenericResponse.ng("链接异常").getBody().toString();
        }
        log.info(response_str);
        return response_str;
    }


    /**
     * 生成签章页面
     *
     * @param no
     * @param user_code
     * @param return_url
     * @param notify_url
     * @return
     */
    public String createH5sgin(String no, String user_code, String return_url, String notify_url) {
        String private_key = PRIVATE_KEY;
        String request_url = REQUEST_URL + "mobileSignView";
        String zqid = ZQID;
        EncryptData ed = new EncryptData();

        Map<String, String> map = new HashMap<>();

        map.put("zqid", zqid);//商户的zqid,该值需要与private_key对应
        map.put("no", no);//已存在的合同编号
        map.put("user_code", user_code);//签署人的user_code
        map.put("sign_type", "WRITTEN");//签章不验证签署
        map.put("return_url", return_url);//同步回调地址:签署成功后,服务器会主动调用该地址,并将请求结果一并返回，若关闭该页面，请求通知结果也会关闭。
        map.put("notify_url", notify_url);//异步回调地址:若用户关闭同步通知调用该页面，后台每三分钟向后台发送请求直到用户拿到success结果。

        String sign_val = ed.encrptData(map, private_key);//对请求进行签名加密

        map.put("sign_val", sign_val);//添加签名值

        String requestHtmlUrl = null;//向服务端发送请求，并接收请求结果
//        try {
//            requestHtmlUrl = HttpRequest.sendPost(request_url, map);
//        } catch (IOException e) {
//            e.printStackTrace();
//            requestHtmlUrl = GenericResponse.ng("链接异常").getBody().toString();
//        }

        try {
            requestHtmlUrl = ZqSubmit.buildRequest(map, request_url, private_key);
        } catch (Exception e) {
            e.printStackTrace();
            return "";
        }
        return requestHtmlUrl;
    }

    /**
     * 获取合同图片地址
     *
     * @param no
     * @return
     */
    public List getImg(String no) {
        String private_key = PRIVATE_KEY; //私钥放置的位置
        String request_url = REQUEST_URL + "getImg";
        String zqid = ZQID;
        EncryptData ed = new EncryptData();

        Map<String, String> map = new HashMap<String, String>();
        map.put("zqid", zqid);//商户的zqid,该值需要与private_key对应
        map.put("no", no);//已存在的合同编号

        String sign_val = ed.encrptData(map, private_key);//对请求进行签名加密

        map.put("sign_val", sign_val);//添加签名值
        String response_str = null;
        List list = new ArrayList();
        try {
            response_str = HttpRequest.sendPost(request_url, map);//向服务端发送请求，并接收请求结果
            JSONObject json = JSONObject.parseObject(response_str);
            if (json.get("code").equals("0")) {
                JSONArray arrJson = json.getJSONArray("imgList");
                for (int i = 0; i < arrJson.size(); i++) {
                    list.add(arrJson.get(i));
                }
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 获取合同图片地址
     * 获取合同pdf地址
     *
     * @param no
     * @return
     */
    public String getPdfUrl(String no) throws Exception {

        ZqContract zqContract = new ZqContract();
        zqContract.setContractNo(no);
        List<ZqContract> list = zqContractMapper.select(zqContract);

        if (list != null && list.size() > 0) {
            Integer dateInt = Integer.valueOf(DateUtils.conver(list.get(0).getCreateTime(), "yyyyMM"));

            if (dateInt < 202009) {
                String private_key = PRIVATE_KEY;
                String request_url = REQUEST_URL + "getPdfUrl";
                String zqid = ZQID;
                EncryptData ed = new EncryptData();

                Map<String, String> map = new HashMap<String, String>();

                map.put("zqid", zqid);//商户的zqid,该值需要与private_key对应
                map.put("no", no);//已存在的合同编号

                String sign_val = ed.encrptData(map, private_key);
                map.put("sign_val", sign_val); //请求参数的签名值
                String response_str = null;//向服务端发送请求，并接收请求结果
                try {
                    response_str = HttpRequest.sendPost(request_url, map);
                    JSONObject json = JSONObject.parseObject(response_str);
                    if (json.get("code").equals("0")) {
                        response_str = json.getString("pdfUrl");
                    } else {
                        throw new Exception(json.getString("msg"));
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                    response_str = "";
                }
                return response_str;
            } else {
                return list.get(0).getContractUrl();
            }
        }
        return "";
    }

    /**
     * 生产模板
     *
     * @param file
     * @return
     */
    public String createTemplate(MultipartFile file) {
        String private_key = PRIVATE_KEY;
        String request_url = REQUEST_URL + "createTemplate";
        String zqid = ZQID;
        EncryptData ed = new EncryptData();

        Map<String, String> map = new HashMap<String, String>();
        map.put("zqid", zqid);// ---------需要用户修改
        byte[] byteArray = new byte[0];
        String response_str = "";
        try {
            byteArray = IOUtils.toByteArray(file.getInputStream());
            String encode = Base64.encode(byteArray);
            map.put("contract", encode);// ---------需要用户修改
            map.put("t_name", "保险经纪服务委托协议");
            String sign_val = ed.encrptData(map, private_key);
            map.put("sign_val", sign_val); // 请求参数的签名
            System.out.println("请求参数：" + map.toString());
            response_str = HttpRequest.sendPost(request_url, map);// 向服务端发送请求，并接收请求结果
            System.out.println("请求结果：" + response_str);// 输出服务器响应结果
        } catch (IOException e) {
            e.printStackTrace();
            response_str = GenericResponse.ng("链接异常").toString();
        }
        log.info(response_str);
        return response_str;
    }

    /**
     * 撤销合同
     *
     * @param no 合同号
     * @return
     */
    public String undoSign(String no) {
        String private_key = PRIVATE_KEY;
        String request_url = REQUEST_URL + "undoSign";
        String zqid = ZQID;
        EncryptData ed = new EncryptData();

        Map<String, String> map = new HashMap<String, String>();

        map.put("zqid", zqid);//商户的zqid,该值需要与private_key对应
        map.put("no", no);//已存在的合同编号

        String sign_val = ed.encrptData(map, private_key);
        map.put("sign_val", sign_val); //请求参数的签名值
        String response_str = null;//向服务端发送请求，并接收请求结果
        try {
            response_str = HttpRequest.sendPost(request_url, map);
        } catch (IOException e) {
            e.printStackTrace();
            response_str = GenericResponse.ng("链接异常").getBody().toString();
        }
        log.info(response_str);
        return response_str;
    }

    /**
     * 合同生效接口
     *
     * @param no
     * @return
     * @throws IOException
     */
    public String completionContract(String no) throws IOException {
        String privateKey = PRIVATE_KEY;
        String requestUrl = REQUEST_URL + "completionContract";
        String zqid = ZQID;
        EncryptData ed = new EncryptData();
        Map<String, String> map = new HashMap<>();
        map.put("zqid", zqid);
        map.put("no", no);
        String signVal = ed.encrptData(map, privateKey);
        map.put("sign_val", signVal);
        String responseStr = HttpRequest.sendPost(requestUrl, map);
        //输出服务器响应结果
        log.info("请求结果：" + responseStr);
        return responseStr;
    }
}
